From a7858a380032403bac2f52a0245cb28ee6d19592 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 22 Nov 2019 20:19:25 +0100
Subject: [PATCH] HACK: steam: Add PE wrapper DLL for lsteamclient.

This is used to pass several Denuvo DRM checks that are picky about
the nature of the module from which Steam procedures are loaded as well
as its basename.
---
 configure                             |   3 +
 configure.ac                          |   2 +
 dlls/steamclient/Makefile.in          |   5 ++
 dlls/steamclient/steamclient.spec     |  56 +++++++++++++
 dlls/steamclient/steamclient_main.c   | 112 ++++++++++++++++++++++++++
 dlls/steamclient64/Makefile.in        |   6 ++
 dlls/steamclient64/steamclient64.spec |  56 +++++++++++++
 7 files changed, 240 insertions(+)
 create mode 100644 dlls/steamclient/Makefile.in
 create mode 100644 dlls/steamclient/steamclient.spec
 create mode 100644 dlls/steamclient/steamclient_main.c
 create mode 100644 dlls/steamclient64/Makefile.in
 create mode 100644 dlls/steamclient64/steamclient64.spec

diff --git a/configure b/configure
index 7f7329a007e..231ce6ce103 100755
--- a/configure
+++ b/configure
@@ -1573,6 +1573,7 @@ enable_sspicli
 enable_stdole2_tlb
 enable_stdole32_tlb
 enable_sti
+enable_steamclient
 enable_strmbase
 enable_strmdll
 enable_strmiids
@@ -20926,6 +20927,8 @@ wine_fn_config_makefile dlls/stdole32.tlb enable_stdole32_tlb
 wine_fn_config_makefile dlls/sti enable_sti
 wine_fn_config_makefile dlls/sti/tests enable_tests
 wine_fn_config_makefile dlls/storage.dll16 enable_win16
+test "x$enable_win64" = xyes || wine_fn_config_makefile dlls/steamclient enable_steamclient
+test "x$enable_win64" = xno || wine_fn_config_makefile dlls/steamclient64 enable_steamclient
 wine_fn_config_makefile dlls/stress.dll16 enable_win16
 wine_fn_config_makefile dlls/strmbase enable_strmbase
 wine_fn_config_makefile dlls/strmdll enable_strmdll
diff --git a/configure.ac b/configure.ac
index 5c77251c9c2..152107d7f15 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3681,6 +3681,8 @@ WINE_CONFIG_MAKEFILE(dlls/stdole32.tlb)
 WINE_CONFIG_MAKEFILE(dlls/sti)
 WINE_CONFIG_MAKEFILE(dlls/sti/tests)
 WINE_CONFIG_MAKEFILE(dlls/storage.dll16,enable_win16)
+WINE_CONFIG_MAKEFILE(dlls/steamclient,enable_steamclient,[test "x$enable_win64" = xyes])
+WINE_CONFIG_MAKEFILE(dlls/steamclient64,enable_steamclient,[test "x$enable_win64" = xno])
 WINE_CONFIG_MAKEFILE(dlls/stress.dll16,enable_win16)
 WINE_CONFIG_MAKEFILE(dlls/strmbase)
 WINE_CONFIG_MAKEFILE(dlls/strmdll)
diff --git a/dlls/steamclient/Makefile.in b/dlls/steamclient/Makefile.in
new file mode 100644
index 00000000000..ad44fb3cc72
--- /dev/null
+++ b/dlls/steamclient/Makefile.in
@@ -0,0 +1,5 @@
+MODULE        = steamclient.dll
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+	steamclient_main.c
diff --git a/dlls/steamclient/steamclient.spec b/dlls/steamclient/steamclient.spec
new file mode 100644
index 00000000000..2b6e52e032b
--- /dev/null
+++ b/dlls/steamclient/steamclient.spec
@@ -0,0 +1,56 @@
+1 cdecl Breakpad_SteamMiniDumpInit(long ptr ptr) STEAMCLIENT_Breakpad_SteamMiniDumpInit
+2 cdecl Breakpad_SteamSetAppID(long) STEAMCLIENT_Breakpad_SteamSetAppID
+3 cdecl Breakpad_SteamSetSteamID(int64) STEAMCLIENT_Breakpad_SteamSetSteamID
+4 cdecl Breakpad_SteamWriteMiniDumpSetComment(ptr) STEAMCLIENT_Breakpad_SteamWriteMiniDumpSetComment
+5 cdecl Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId(long long) STEAMCLIENT_Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId
+6 cdecl CreateInterface(ptr ptr) STEAMCLIENT_CreateInterface
+7 stub Steam_BConnected
+8 cdecl Steam_BGetCallback(long ptr ptr) STEAMCLIENT_Steam_BGetCallback
+9 stub Steam_BLoggedOn
+10 stub Steam_BReleaseSteamPipe
+11 stub Steam_ConnectToGlobalUser
+12 stub Steam_CreateGlobalUser
+13 stub Steam_CreateLocalUser
+14 stub Steam_CreateSteamPipe
+15 cdecl Steam_FreeLastCallback(long) STEAMCLIENT_Steam_FreeLastCallback
+16 stub Steam_GSBLoggedOn
+17 stub Steam_GSBSecure
+18 stub Steam_GSGetSteam2GetEncryptionKeyToSendToNewClient
+19 stub Steam_GSGetSteamID
+20 stub Steam_GSLogOff
+21 stub Steam_GSLogOn
+22 stub Steam_GSRemoveUserConnect
+23 stub Steam_GSSendSteam2UserConnect
+24 stub Steam_GSSendSteam3UserConnect
+25 stub Steam_GSSendUserDisconnect
+26 stub Steam_GSSendUserStatusResponse
+27 stub Steam_GSSetServerType
+28 stub Steam_GSSetSpawnCount
+29 stub Steam_GSUpdateStatus
+30 cdecl Steam_GetAPICallResult(long int64 ptr long long ptr) STEAMCLIENT_Steam_GetAPICallResult
+31 stub Steam_GetGSHandle
+32 stub Steam_InitiateGameConnection
+33 stub Steam_LogOff
+34 stub Steam_LogOn
+35 cdecl Steam_ReleaseThreadLocalMemory(long) STEAMCLIENT_Steam_ReleaseThreadLocalMemory
+36 stub Steam_ReleaseUser
+37 stub Steam_SetLocalIPBinding
+38 stub Steam_TerminateGameConnection
+39 stub hid_close
+40 stub hid_enumerate
+41 stub hid_error
+42 stub hid_exit
+43 stub hid_free_enumeration
+44 stub hid_get_feature_report
+45 stub hid_get_indexed_string
+46 stub hid_get_manufacturer_string
+47 stub hid_get_product_string
+48 stub hid_get_serial_number_string
+49 stub hid_init
+50 stub hid_open
+51 stub hid_open_path
+52 stub hid_read
+53 stub hid_read_timeout
+54 stub hid_send_feature_report
+55 stub hid_set_nonblocking
+56 stub hid_write
diff --git a/dlls/steamclient/steamclient_main.c b/dlls/steamclient/steamclient_main.c
new file mode 100644
index 00000000000..de9e62c8322
--- /dev/null
+++ b/dlls/steamclient/steamclient_main.c
@@ -0,0 +1,112 @@
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(steamclient);
+
+static HMODULE lsteamclient;
+static void (CDECL *pBreakpad_SteamMiniDumpInit)(UINT32, char *, char *);
+static void (CDECL *pBreakpad_SteamSetAppID)(UINT32);
+static int (CDECL *pBreakpad_SteamSetSteamID)(UINT64);
+static int (CDECL *pBreakpad_SteamWriteMiniDumpSetComment)(char *);
+static void (CDECL *pBreakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId)(int, int);
+static void *(CDECL *pCreateInterface)(char *, int *);
+static BOOL (CDECL *pSteam_BGetCallback)(INT32, void *, INT32 *);
+static BOOL (CDECL *pSteam_FreeLastCallback)(INT32);
+static BOOL (CDECL *pSteam_GetAPICallResult)(INT32, UINT64, void *, int, int, BOOL *);
+static void (CDECL *pSteam_ReleaseThreadLocalMemory)(int);
+
+BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
+{
+    TRACE("(%p, %u, %p)\n", instance, reason, reserved);
+
+    switch (reason)
+    {
+        case DLL_PROCESS_ATTACH:
+            lsteamclient = LoadLibraryA("lsteamclient");
+            if (!lsteamclient)
+                return FALSE;
+
+            pBreakpad_SteamMiniDumpInit = (void*)GetProcAddress(lsteamclient,"Breakpad_SteamMiniDumpInit");
+            pBreakpad_SteamSetAppID = (void*)GetProcAddress(lsteamclient,"Breakpad_SteamSetAppID");
+            pBreakpad_SteamSetSteamID = (void*)GetProcAddress(lsteamclient,"Breakpad_SteamSetSteamID");
+            pBreakpad_SteamWriteMiniDumpSetComment = (void*)GetProcAddress(lsteamclient,"Breakpad_SteamWriteMiniDumpSetComment");
+            pBreakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId = (void*)GetProcAddress(lsteamclient,"Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId");
+            pCreateInterface = (void*)GetProcAddress(lsteamclient,"CreateInterface");
+            pSteam_BGetCallback = (void*)GetProcAddress(lsteamclient,"Steam_BGetCallback");
+            pSteam_FreeLastCallback = (void*)GetProcAddress(lsteamclient,"Steam_FreeLastCallback");
+            pSteam_GetAPICallResult = (void*)GetProcAddress(lsteamclient,"Steam_GetAPICallResult");
+            pSteam_ReleaseThreadLocalMemory = (void*)GetProcAddress(lsteamclient,"Steam_ReleaseThreadLocalMemory");
+
+            TRACE("Forwarding DLL (lsteamclient) loaded (%p)\n", lsteamclient);
+            break;
+        case DLL_PROCESS_DETACH:
+            FreeLibrary(lsteamclient);
+            TRACE("Forwarding DLL (lsteamclient) freed\n");
+            break;
+    }
+
+    return TRUE;
+}
+
+void CDECL STEAMCLIENT_Breakpad_SteamMiniDumpInit(UINT32 a, char *b, char *c)
+{
+    TRACE("\n");
+    pBreakpad_SteamMiniDumpInit(a, b, c);
+}
+
+void CDECL STEAMCLIENT_Breakpad_SteamSetAppID(UINT32 a)
+{
+    TRACE("\n");
+    pBreakpad_SteamSetAppID(a);
+}
+
+int CDECL STEAMCLIENT_Breakpad_SteamSetSteamID(UINT64 a)
+{
+    TRACE("\n");
+    return pBreakpad_SteamSetSteamID(a);
+}
+
+int CDECL STEAMCLIENT_Breakpad_SteamWriteMiniDumpSetComment(char *a)
+{
+    TRACE("\n");
+    return pBreakpad_SteamWriteMiniDumpSetComment(a);
+}
+
+void CDECL STEAMCLIENT_Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId(int a, int b)
+{
+    TRACE("\n");
+    pBreakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId(a, b);
+}
+
+void *CDECL STEAMCLIENT_CreateInterface(char *a, int *b)
+{
+    TRACE("\n");
+    return pCreateInterface(a, b);
+}
+
+BOOL CDECL STEAMCLIENT_Steam_BGetCallback(INT32 a, void *b, INT32 *c)
+{
+    TRACE("\n");
+    return pSteam_BGetCallback(a, b, c);
+}
+
+BOOL CDECL STEAMCLIENT_Steam_FreeLastCallback(INT32 a)
+{
+    TRACE("\n");
+    return pSteam_FreeLastCallback(a);
+}
+
+BOOL CDECL STEAMCLIENT_Steam_GetAPICallResult(INT32 a, UINT64 b, void *c, int d, int e, BOOL *f)
+{
+    TRACE("\n");
+    return pSteam_GetAPICallResult(a, b, c, d, e, f);
+}
+
+void CDECL STEAMCLIENT_Steam_ReleaseThreadLocalMemory(int a)
+{
+    TRACE("\n");
+    pSteam_ReleaseThreadLocalMemory(a);
+}
diff --git a/dlls/steamclient64/Makefile.in b/dlls/steamclient64/Makefile.in
new file mode 100644
index 00000000000..ff2feff56a7
--- /dev/null
+++ b/dlls/steamclient64/Makefile.in
@@ -0,0 +1,6 @@
+MODULE        = steamclient64.dll
+PARENTSRC     = ../steamclient
+EXTRADLLFLAGS = -mno-cygwin
+
+C_SRCS = \
+	steamclient_main.c
diff --git a/dlls/steamclient64/steamclient64.spec b/dlls/steamclient64/steamclient64.spec
new file mode 100644
index 00000000000..2b6e52e032b
--- /dev/null
+++ b/dlls/steamclient64/steamclient64.spec
@@ -0,0 +1,56 @@
+1 cdecl Breakpad_SteamMiniDumpInit(long ptr ptr) STEAMCLIENT_Breakpad_SteamMiniDumpInit
+2 cdecl Breakpad_SteamSetAppID(long) STEAMCLIENT_Breakpad_SteamSetAppID
+3 cdecl Breakpad_SteamSetSteamID(int64) STEAMCLIENT_Breakpad_SteamSetSteamID
+4 cdecl Breakpad_SteamWriteMiniDumpSetComment(ptr) STEAMCLIENT_Breakpad_SteamWriteMiniDumpSetComment
+5 cdecl Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId(long long) STEAMCLIENT_Breakpad_SteamWriteMiniDumpUsingExceptionInfoWithBuildId
+6 cdecl CreateInterface(ptr ptr) STEAMCLIENT_CreateInterface
+7 stub Steam_BConnected
+8 cdecl Steam_BGetCallback(long ptr ptr) STEAMCLIENT_Steam_BGetCallback
+9 stub Steam_BLoggedOn
+10 stub Steam_BReleaseSteamPipe
+11 stub Steam_ConnectToGlobalUser
+12 stub Steam_CreateGlobalUser
+13 stub Steam_CreateLocalUser
+14 stub Steam_CreateSteamPipe
+15 cdecl Steam_FreeLastCallback(long) STEAMCLIENT_Steam_FreeLastCallback
+16 stub Steam_GSBLoggedOn
+17 stub Steam_GSBSecure
+18 stub Steam_GSGetSteam2GetEncryptionKeyToSendToNewClient
+19 stub Steam_GSGetSteamID
+20 stub Steam_GSLogOff
+21 stub Steam_GSLogOn
+22 stub Steam_GSRemoveUserConnect
+23 stub Steam_GSSendSteam2UserConnect
+24 stub Steam_GSSendSteam3UserConnect
+25 stub Steam_GSSendUserDisconnect
+26 stub Steam_GSSendUserStatusResponse
+27 stub Steam_GSSetServerType
+28 stub Steam_GSSetSpawnCount
+29 stub Steam_GSUpdateStatus
+30 cdecl Steam_GetAPICallResult(long int64 ptr long long ptr) STEAMCLIENT_Steam_GetAPICallResult
+31 stub Steam_GetGSHandle
+32 stub Steam_InitiateGameConnection
+33 stub Steam_LogOff
+34 stub Steam_LogOn
+35 cdecl Steam_ReleaseThreadLocalMemory(long) STEAMCLIENT_Steam_ReleaseThreadLocalMemory
+36 stub Steam_ReleaseUser
+37 stub Steam_SetLocalIPBinding
+38 stub Steam_TerminateGameConnection
+39 stub hid_close
+40 stub hid_enumerate
+41 stub hid_error
+42 stub hid_exit
+43 stub hid_free_enumeration
+44 stub hid_get_feature_report
+45 stub hid_get_indexed_string
+46 stub hid_get_manufacturer_string
+47 stub hid_get_product_string
+48 stub hid_get_serial_number_string
+49 stub hid_init
+50 stub hid_open
+51 stub hid_open_path
+52 stub hid_read
+53 stub hid_read_timeout
+54 stub hid_send_feature_report
+55 stub hid_set_nonblocking
+56 stub hid_write

From f1a778c4f1c854be135b8bd9e320dde98fcca78a Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Tue, 12 Nov 2019 11:44:07 -0600
Subject: [PATCH] HACK: steam: ntdll: Load both native and builtin steamclient.

This loads both libraries and swap between them whenever useful in
ordet to pass the various DRM checks.
---
 dlls/ntdll/loader.c | 97 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 8dfabde44c3..b25c48b52ca 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1541,6 +1541,75 @@ static void thread_attach(void)
     }
 }
 
+#define LDR_STEAM_INTERNAL 0x20000000
+
+#ifdef _WIN64
+static WCHAR builtin_steamclient_w[] = {'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2','\\',
+                                        's','t','e','a','m','c','l','i','e','n','t','6','4','.','d','l','l',0};
+static WCHAR native_steamclient_w[] = {'C',':','\\','P','r','o','g','r','a','m',' ','F','i','l','e','s',' ','(','x','8','6',')','\\','S','t','e','a','m','\\',
+                                       's','t','e','a','m','c','l','i','e','n','t','6','4','.','d','l','l',0};
+static WCHAR steamclient_w[] = {'s','t','e','a','m','c','l','i','e','n','t','6','4',0};
+#else
+static WCHAR builtin_steamclient_w[] = {'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2','\\',
+                                        's','t','e','a','m','c','l','i','e','n','t','.','d','l','l',0};
+static WCHAR native_steamclient_w[] = {'C',':','\\','P','r','o','g','r','a','m',' ','F','i','l','e','s',' ','(','x','8','6',')','\\','S','t','e','a','m','\\',
+                                       's','t','e','a','m','c','l','i','e','n','t','.','d','l','l',0};
+static WCHAR steamclient_w[] = {'s','t','e','a','m','c','l','i','e','n','t',0};
+#endif
+static WCHAR lsteamclient_w[] = {'l','s','t','e','a','m','c','l','i','e','n','t',0};
+
+static WCHAR *strstriW( const WCHAR *str, const WCHAR *sub )
+{
+    while (*str)
+    {
+        const WCHAR *p1 = str, *p2 = sub;
+        while (*p1 && *p2 && tolowerW(*p1) == tolowerW(*p2)) { p1++; p2++; }
+        if (!*p2) return (WCHAR *)str;
+        str++;
+    }
+    return NULL;
+}
+
+static HMODULE get_builtin_steamclient_mod(BOOL load_module)
+{
+    HMODULE module = 0;
+    UNICODE_STRING steamclient_us;
+
+    RtlInitUnicodeString(&steamclient_us, builtin_steamclient_w);
+    LdrGetDllHandle(NULL, LDR_STEAM_INTERNAL, &steamclient_us, &module);
+    if (!module && load_module) LdrLoadDll(NULL, LDR_STEAM_INTERNAL, &steamclient_us, &module);
+    return module;
+}
+
+static HMODULE get_native_steamclient_mod(BOOL load_module)
+{
+    HMODULE module = 0;
+    UNICODE_STRING steamclient_us;
+
+    RtlInitUnicodeString(&steamclient_us, native_steamclient_w);
+    LdrGetDllHandle(NULL, LDR_STEAM_INTERNAL, &steamclient_us, &module);
+    if (!module && load_module) LdrLoadDll(NULL, LDR_STEAM_INTERNAL, &steamclient_us, &module);
+    return module;
+}
+
+static void swap_native_to_builtin_steamclient_hack(HMODULE *module)
+{
+    if (*module && *module == get_native_steamclient_mod(FALSE))
+    {
+        WARN("HACK: Swapping native to builtin steamclient module.\n");
+        *module = get_builtin_steamclient_mod(TRUE);
+    }
+}
+
+static void swap_builtin_to_native_steamclient_hack(HMODULE *module)
+{
+    if (*module && *module == get_builtin_steamclient_mod(FALSE))
+    {
+        WARN("HACK: Swapping builtin to native steamclient module.\n");
+        *module = get_native_steamclient_mod(TRUE);
+    }
+}
+
 /******************************************************************
  *		LdrDisableThreadCalloutsForDll (NTDLL.@)
  *
@@ -1573,6 +1642,8 @@ NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod)
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
 
+    swap_builtin_to_native_steamclient_hack((HMODULE*)&addr);
+
     mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
     for (entry = mark->Flink; entry != mark; entry = entry->Flink)
     {
@@ -1711,7 +1782,6 @@ NTSTATUS WINAPI LdrUnlockLoaderLock( ULONG flags, ULONG_PTR magic )
     return STATUS_SUCCESS;
 }
 
-
 /******************************************************************
  *		LdrGetProcedureAddress  (NTDLL.@)
  */
@@ -1723,6 +1793,7 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
     NTSTATUS ret = STATUS_PROCEDURE_NOT_FOUND;
 
     RtlEnterCriticalSection( &loader_section );
+    swap_native_to_builtin_steamclient_hack(&module);
 
     /* check if the module itself is invalid to return the proper error */
     if (!get_modref( module )) ret = STATUS_DLL_NOT_FOUND;
@@ -2331,6 +2402,12 @@ static NTSTATUS open_dll_file( UNICODE_STRING *nt_name, WINE_MODREF **pwm,
     }
     if (!status && !is_valid_binary( *module, image_info ))
     {
+        if (strstriW(nt_name->Buffer, native_steamclient_w))
+        {
+            WARN("HACK: Accepting native steamclient module from %s, even though it's the wrong arch.\n", debugstr_us(nt_name));
+            return STATUS_SUCCESS;
+        }
+
         TRACE( "%s is for arch %x, continuing search\n", debugstr_us(nt_name), image_info->machine );
         NtUnmapViewOfSection( NtCurrentProcess(), *module );
         *module = NULL;
@@ -2970,6 +3047,14 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
         return STATUS_SUCCESS;
     }
 
+    if (nts != STATUS_DLL_NOT_FOUND && strstriW(libname, native_steamclient_w))
+    {
+        WARN("HACK: Allocating native steamclient module from %s, but not loading dll.\n", debugstr_w(libname));
+        if (!(*pwm = alloc_module( module, &nt_name, FALSE )))
+            return STATUS_NO_MEMORY;
+        return STATUS_SUCCESS;
+    }
+
     if (nts && nts != STATUS_DLL_NOT_FOUND && nts != STATUS_INVALID_IMAGE_NOT_MZ) goto done;
 
     main_exe = get_modref( NtCurrentTeb()->Peb->ImageBaseAddress );
@@ -3088,6 +3173,14 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
 
     RtlEnterCriticalSection( &loader_section );
 
+    if (!(flags & LDR_STEAM_INTERNAL) && strstriW(libname->Buffer, steamclient_w) && !strstriW(libname->Buffer, lsteamclient_w))
+    {
+        *hModule = get_builtin_steamclient_mod(TRUE);
+        swap_builtin_to_native_steamclient_hack(hModule);
+        RtlLeaveCriticalSection( &loader_section );
+        return *hModule ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
+    }
+
     if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
     nts = load_dll( path_name, libname->Buffer, dllW, flags, &wm );
 
@@ -3133,6 +3226,7 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
     }
     RtlFreeUnicodeString( &nt_name );
 
+    if (!(flags & LDR_STEAM_INTERNAL)) swap_builtin_to_native_steamclient_hack(base);
     RtlLeaveCriticalSection( &loader_section );
     TRACE( "%s -> %p (load path %s)\n", debugstr_us(name), status ? NULL : *base, debugstr_w(load_path) );
     return status;
@@ -3953,6 +4047,7 @@ PVOID WINAPI RtlPcToFileHeader( PVOID pc, PVOID *address )
 
     RtlEnterCriticalSection( &loader_section );
     if (!LdrFindEntryForAddress( pc, &module )) ret = module->DllBase;
+    swap_builtin_to_native_steamclient_hack((HMODULE*)&ret);
     RtlLeaveCriticalSection( &loader_section );
     *address = ret;
     return ret;
